package com.liuya.safe.policy.controller;

import com.liuya.common.SpringUtils;
import com.liuya.common.WebUtil;
import com.liuya.entitle.ScriptTestResult;
import com.liuya.safe.model.SafeUser;
import com.liuya.safe.policy.handler.AbstractPolicyDesignHandler;
import com.liuya.safe.policy.service.QueryManagerService;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.ui.ModelMap;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;

public abstract class AbstractPolicyTestController extends AbstractTestController {

    private static final Log log = LogFactory.getLog(AbstractPolicyTestController.class);

    public Object testPolicy(HttpServletRequest req, HttpServletResponse rep, ModelMap modelMap){
        AbstractPolicyDesignHandler handler = getPolicyHandler(req);
        req.setAttribute("handler", handler);

        QueryManagerService queryMng = (QueryManagerService) SpringUtils.getBean("queryManagerService");
        handler.prepareTest(queryMng);
        return handler.getTestMainPage();
    }

    public Object returnMain(HttpServletRequest req, HttpServletResponse rep, ModelMap modelMap){
        AbstractPolicyDesignHandler handler = getPolicyHandler(req);
        req.setAttribute("handler", handler);
        // remove handler from session
        req.getSession().removeAttribute(getPolicyHandlerAttributeKey(req));

        return "redirect:/" + handler.getManagePage();
    }

    public Object runTest(HttpServletRequest req, HttpServletResponse rep, ModelMap modelMap) {
        AbstractPolicyDesignHandler handler = getPolicyHandler(req);
        req.setAttribute("handler", handler);

        boolean testUserNeeded = handler.isTestUserNeeded();
        String[] testBusinessDataFields = handler.getTestBusinessDataFields();
        String[] testContextFields = handler.getTestContextFields();

        SafeUser testUser = buildTestUser(req, testUserNeeded);
        String errMsg = "";
        Object testBdData = null;
        Map testCtx = null;
        try {
            testBdData = buildTestBusinessData(req, testBusinessDataFields);
            testCtx = buildTestContext(req, testContextFields);
        } catch (Exception e) {
            errMsg = "<font color='red'><pre>" + e.getMessage() + "</pre></font>";
        }

        ScriptTestResult testResult = handler.run(testUser, testBdData, testCtx);
        req.setAttribute("testResult", testResult);
        req.setAttribute("errMsg", errMsg);

        return handler.getShowTestResultPage();
    }

    public Object save(HttpServletRequest req, HttpServletResponse rep, ModelMap modelMap){
        AbstractPolicyDesignHandler handler = getPolicyHandler(req);
        req.setAttribute("handler", handler);
        // remove handler from session
        req.getSession().removeAttribute(getPolicyHandlerAttributeKey(req));
        String id = WebUtil.getStringParameter(req, "id", "-23");
        return handler.save(id);
    }

    public Object setBusinessDataClass(HttpServletRequest req, HttpServletResponse rep, ModelMap modelMap){
        String oper = req.getParameter("oper");
        AbstractPolicyDesignHandler handler = getPolicyHandler(req);
        req.setAttribute("handler", handler);

        String bdClass = req.getParameter("businessDataClass");
        handler.setBusinessDataClass(bdClass);

        req.setAttribute("testBusinessDataFields", handler.getTestBusinessDataFields());
        req.setAttribute("testBusinessDataFieldTypes", handler.getTestBusinessDataFieldTypes());
        req.setAttribute("bdClass", bdClass);

        return "common/inputTestBusinessData";
    }

    public abstract AbstractPolicyDesignHandler createPolicyHandler(HttpServletRequest req);

    public abstract String getPolicyHandlerAttributeKey(HttpServletRequest req);

    private AbstractPolicyDesignHandler getPolicyHandler(HttpServletRequest req) {
        String oper = req.getParameter("oper");
        String key = getPolicyHandlerAttributeKey(req);
        AbstractPolicyDesignHandler handler = (AbstractPolicyDesignHandler) req.getSession().getAttribute(key);

        if (handler == null || "loadFresh".equals(oper)) {
            handler = createPolicyHandler(req);

            // save into session, will be removed when policy is saved
            req.getSession().setAttribute(key, handler);
        }

        return handler;
    }

    protected abstract void updateHandler(HttpServletRequest req, Object handler);

}